#include "wxscodercontext.h"
#include "wxsflags.h"

using namespace wxsFlags;

void wxsCoderContext::AddHeader( const wxString& Header, const wxString& DeclaredClass, long HeaderFlags ) {
  bool IsLocal = ( HeaderFlags & hfLocal ) != 0;
  bool InPch = ( HeaderFlags & hfInPCH ) != 0;
  bool ForbidFwd = ( HeaderFlags & hfForbidFwd ) != 0;
  bool AddFwd = false;
  if( !( m_Flags & flSource ) ) {
    if( IsLocal ) {
      return;
    }
    if( m_Flags & flLocal ) {
      return;
    }
  }
  if( ( m_Flags & flFwdDeclar ) && ( m_Flags & flPointer ) && !ForbidFwd && !IsLocal && !( m_Flags & flRoot ) ) {
    IsLocal = true;
    AddFwd = true;
  }
  if( !( m_Flags & flPchFilter ) ) {
    InPch = false;
  }
  wxStringSet& Global = m_GlobalHeaders;
  wxStringSet& GlobalNonPCH = m_GlobalHeadersNonPCH;
  wxStringSet& Local = m_LocalHeaders;
  wxStringSet& LocalNonPCH  = m_LocalHeadersNonPCH;
  wxStringSet& FwdDcl = m_ForwardDeclarations;
  wxStringSet& FwdDclNonPCH = m_ForwardDeclarationsNonPCH;
  if( IsLocal ) {
    if( Global.find( Header ) == Global.end() && GlobalNonPCH.find( Header ) == GlobalNonPCH.end() ) {
      ( InPch ? Local : LocalNonPCH ) . insert( Header );
      if( AddFwd ) {
        ( InPch ? FwdDcl : FwdDclNonPCH ) . insert( DeclaredClass );
      }
    }
  } else {
    if( !InPch ) {
      Global.erase( Header );
      GlobalNonPCH.insert( Header );
    } else {
      if( GlobalNonPCH.find( Header ) == GlobalNonPCH.end() ) {
        Global.insert( Header );
      }
    }
    Local.erase( Header );
    LocalNonPCH.erase( Header );
    FwdDcl.erase( DeclaredClass );
    FwdDclNonPCH.erase( DeclaredClass );
  }
}

void wxsCoderContext::AddDeclaration( const wxString& Declaration ) {
  if( m_Flags & flRoot ) {
    return;
  }
  if( !( m_Flags & flSource ) ) {
    if( m_Flags & flLocal ) {
      return;
    }
  }
  if( m_Flags & flLocal ) {
    m_LocalDeclarations.insert( Declaration );
  } else {
    m_GlobalDeclarations.insert( Declaration );
  }
}

void wxsCoderContext::AddXRCFetchingCode( const wxString& Code ) {
  if( m_Flags & flRoot ) {
    return;
  }
  if( m_Flags & flLocal ) {
    return;
  }
  if( m_Flags & flMixed ) {
    m_XRCFetchingCode.Append( Code );
  }
}

void wxsCoderContext::AddBuildingCode( const wxString& Code ) {
  if( m_Flags & flSource ) {
    m_BuildingCode.Append( Code );
  }
}

void wxsCoderContext::AddEventCode( const wxString& Code ) {
  m_EventsConnectingCode.Append( Code );
}

void wxsCoderContext::AddIdCode( const wxString& Enumeration, const wxString& Initialization ) {
  if( m_Flags & flRoot ) {
    return;
  }
  if( m_Flags & flSource ) {
    if( m_IdEnumerations.Index( Enumeration ) == wxNOT_FOUND ) {
      m_IdEnumerations.Add( Enumeration );
      m_IdInitializions.Add( Initialization );
    }
  }
}

wxString wxsCoderContext::GetUniqueName( const wxString& Prefix ) {
  wxString& MapEntry = m_Extra[_T( "__Counter_of_" ) + Prefix];
  MapEntry.Append( _T( '*' ) );
  return wxString::Format( _T( "%s_%d" ), Prefix.c_str(), ( int )MapEntry.Length() );
}
